import MusicManager from "../../MusicManager";
import HealthPoint, { Killer } from "../funcObj/interface/HealthPoint";
import { FacilityType, GamePropType } from "../info/GameEnum";
import { Global } from "../info/Global";
import GameManager from "../manager/GameManager";
import NodePoolManager from "../manager/NodePoolManager";
import Player from "../player/Player";
import FacilityHood from "../prop/FacilityHood";
import FacilityRecycle from "../prop/FacilityRecycle";
import FacilityRepair from "../prop/FacilityRepair";
import Facility from "./Facility";

const { ccclass, property } = cc._decorator;

/**
 * 有血量条的设施
 */
@ccclass
export default abstract class DestructibleFacility extends Facility implements HealthPoint {

    public static EventType = {
        摧毁: "摧毁",
        发射成功: "发射成功",
    }

    /**
    * 血量条
    */
    @property(cc.ProgressBar)
    hpProgress: cc.ProgressBar = null;

    player: Player;
    /**
     * 最大生命值
     */
    maxHp: number;

    /**
     * 当前生命值
     */
    currentHp: number;

    _level: number;

    price: { diamond: number, oil: number }

    /**
     * 威胁值
     */
    threatValue: number;

    public get level(): number {
        return this._level;
    }

    public set level(v: number) {
        this._level = v;
    }

    init(player: Player, ...args: any[])
    init(player: Player) {
        this.player = player;
        this.facilityInfo = Global.getFacilityInfo<any>(this.facilityType);
        this.level = 0;
        this.threatValue = this.facilityInfo.威胁值;
        this.initHp();
        this.addProp();
    }

    public initHp() {
        this.maxHp = 100;
        if (this.facilityInfo) {
            this.maxHp = this.facilityInfo["生命值"] ?? this.facilityInfo["每等级生命值"][this.level];
        }
        this.maxHp *= (100 + Global.FacilityInfo[FacilityType.主基地].建筑血量.每等级加成[this.player.buildingHealthLevel]) / 100
        this.hpProgress.node.children[0].getComponent(cc.Sprite).spriteFrame = this.player.facilityHpColor;
        this.currentHp = this.maxHp;
        this.hpProgress.node.active = false;
        this.hpProgress.progress = 1;
    }

    /**
     * 回复生命值
     */
    repairHp(hp: number): void {
        this.currentHp = Math.min(this.maxHp, this.currentHp + hp);
        this.hpProgress.node.active = this.currentHp < this.maxHp;
        this.hpProgress.progress = this.currentHp / this.maxHp;
    }

    /**
     * 减少生命
     * @param killer 攻击者,
     * @returns 
     */
    reducedHp(killer: Killer): boolean {
        this.player.node.emit(Player.EventType.我的设施被攻击, this, killer);
        // 如果有防护罩
        let hood = this.getComponentInChildren(FacilityHood);
        if (hood) {
            return hood.reducedHp(killer);
        }
        let rate = 1 - Global.FacilityInfo[FacilityType.主基地].建筑防御.每等级加成[this.player.buildingDefenseLevel] / 100;
        killer.domage = Math.max(1, Math.ceil(killer.domage * rate));
        this.currentHp = Math.max(0, this.currentHp - killer.domage);
        this.hpProgress.progress = this.currentHp / this.maxHp;
        this.hpProgress.node.active = this.currentHp < this.maxHp;
        if (this.currentHp == 0) {
            this.die(killer);
            return true;
        } else {
            return false;
        }
    }

    die(killer: Killer) {
        MusicManager.instance.play(MusicManager.instance.build_die, this.node);
        //删除GameManager.MapArray记录录，删除玩家的记录
        this.locations.forEach(location => GameManager.instance.setFacilityMapArray(null, location, false))
        let index = this.player.facilityArr[this.facilityType].findIndex((item) => item == this)
        this.player.facilityArr[this.facilityType].splice(index, 1);
        this.player.node.targetOff(this);
        //回收并播放摧毁动画 
        GameManager.instance.addFacilityExploadEffect(this.facilityType, this.node.position, this.node.getContentSize());
        this.node.emit(DestructibleFacility.EventType.摧毁);
        this.node.off(DestructibleFacility.EventType.摧毁);
        NodePoolManager.instance.recycle(this.node);
    }

    levelUp() {
        let facilityInfo = this.facilityInfo;
        if (!facilityInfo.每等级升级要求) {
            return cc.error("无法升级");
        }

        let upgradePrice = facilityInfo.每等级升级要求[this.level];

        if(!upgradePrice){
            return cc.error("无法升级");
        }

        MusicManager.instance.play(MusicManager.instance.build_up, this.node);
        this.player.diamond -= upgradePrice.diamond;
        this.player.oil -= upgradePrice.oil;
        this.price = { diamond: upgradePrice.diamond, oil: upgradePrice.oil };
        this.level++;
        this.threatValue *= 1.5;
        this.initHp();
    }

    protected addProp() {
        if (this.player.props[GamePropType.能量罩]) {
            let hood = NodePoolManager.instance.obtain(NodePoolManager.instance.facilityHood);
            hood.parent = this.node;
            hood.getComponent(FacilityHood).init(this);
        }

        if (this.player.props[GamePropType.维修]) {
            let hood = NodePoolManager.instance.obtain(NodePoolManager.instance.facilityRepair);
            hood.parent = this.node;
            hood.getComponent(FacilityRepair).init(this);
        }

        if (this.player.props[GamePropType.回收]) {
            let recycle = NodePoolManager.instance.obtain(NodePoolManager.instance.facilityRecycle);
            recycle.parent = this.node;
            recycle.getComponent(FacilityRecycle).init(this);
        }
    }

}
